using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using Oracle.ManagedDataAccess.Client;
using MySql.Data.MySqlClient;
using System.Data.OleDb;

namespace Weight.Base
{
    public interface IDbSession :IDisposable
    {
        /// <summary>
        /// 数据库连接对象
        /// </summary>
         IDbConnection Connection { get;  }

        /// <summary>
        /// 事务对象
        /// </summary>
         IDbTransaction Transaction { get; }

        /// <summary>
        /// 提交事务
        /// </summary>
        void Commit();

        /// <summary>
        /// 回滚事务
        /// </summary>
        void RollBack();
    }

    public class DbSession : IDbSession
    {
        /// <summary>
        /// 数据库连接对象
        /// </summary>
        private IDbConnection _conn;

        /// <summary>
        /// 数据库事务
        /// </summary>
        private IDbTransaction _transaction;

 
        public IDbConnection Connection
        {
            get
            {
                return _conn;
            }
        }
        public IDbTransaction Transaction {
            get
            {
                return _transaction;
            }
        }

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="conn"></param>
        public DbSession(IDbConnection conn)
        {
            _conn = conn;
        }

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="conn"></param>
        public DbSession(IDbConnection conn, IDbTransaction trans)
        {
            _conn = conn;
            _transaction = trans;
        }


        /// <summary>
        /// 提交事务
        /// </summary>

        public void Commit()
        {
            _transaction.Commit();
            _transaction = null;
        }

        /// <summary>
        /// 回滚事务
        /// </summary>
        public void RollBack()
        {
            _transaction.Rollback();
            _transaction = null;
        }

        #region IDisposable Support
        private bool disposedValue = false; // 要检测冗余调用
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                  if(_conn != null)
                    {
                        if(_conn.State !=  ConnectionState.Closed)
                        {
                            if(_transaction != null)
                            {
                                _transaction.Dispose();
                            }
                            _conn.Close();
                            _conn = null;
                        }
                    }
                }

                disposedValue = true;
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion
    }

    public class SessionFactory
    {
        /// <summary>
        /// 创建数据库连接对象
        /// </summary>
        /// <returns></returns>
        private static IDbConnection CreateConnectionByProvider()
        {
            string connStr = ServiceManager.SystemConfig.DbConn.ToString();
            if (connStr.Length == 0) { LogHelper.WriteLog("没有配置数据库类型，请配置数据库类型");return null; }
            IDbConnection conn = null;
            string dataBaseType = ServiceManager.SystemConfig.DbConn.DbType.Type;
            switch(dataBaseType)
            {
                case "SqlServer":
                    conn = new SqlConnection(connStr);
                    break;
                case "Oracl":
                    conn = new OracleConnection(connStr);
                    break;
                case "MySql":
                    conn = new MySqlConnection(connStr);
                    break;
                default:
                    break;
            }

            return conn;
        }

        /// <summary>
        /// 创建数据库连接对象
        /// </summary>
        /// <returns></returns>
        private static IDbConnection CreateImgConnectionByProvider(string year)
        {
            string connStr = ServiceManager.SystemConfig.DbConn.ToImgString(year, ServiceManager.SystemConfig.CompanyName.ToString());
            if (connStr.Length == 0) { LogHelper.WriteLog("没有配置数据库类型，请配置数据库类型"); return null; }
            IDbConnection conn = null;
            string dataBaseType = ServiceManager.SystemConfig.DbConn.DbType.Type;
            switch (dataBaseType)
            {
                case "SqlServer":
                    conn = new SqlConnection(connStr);
                    break;
                case "Oracl":
                    conn = new OracleConnection(connStr);
                    break;
                case "MySql":
                    conn = new MySqlConnection(connStr);
                    break;
                default:
                    break;
            }

            return conn;
        }

        /// <summary>
        ///创建数据库的连接
        /// </summary>
        /// <returns>数据库连接</returns>
        public static IDbConnection CreateConnection()
        {
            IDbConnection conn = CreateConnectionByProvider();
            if(conn.State == ConnectionState.Closed)
            {
                conn.Open();
            }
            return conn;
        }

        /// <summary>
        ///创建数据库的连接
        /// </summary>
        /// <returns>数据库连接</returns>
        public static IDbConnection CreateImageConnection(string year)
        {
            IDbConnection conn = CreateImgConnectionByProvider(year);
            if (conn.State == ConnectionState.Closed)
            {
                conn.Open();
            }
            return conn;
        }

        /// <summary>
        /// 创建数据库连接会话
        /// </summary>
        /// <returns></returns>
        public static  IDbSession CreateSession()
        {
            IDbConnection conn = CreateConnectionByProvider();
            IDbSession session = new DbSession(conn);
            return session;
        }


        /// <summary>
        /// 创建数据库的事务会话
        /// </summary>
        /// <param name="conn">数据库连接</param>
        /// <param name="trans">事务对象</param>
        /// <returns></returns>
        public static IDbSession CreateTransSession( IsolationLevel isolation = IsolationLevel.ReadCommitted)
        {
            IDbConnection conn = CreateConnection();
            if (conn.State == ConnectionState.Closed)
            {
                conn.Open();
            }
            IDbTransaction tran = conn.BeginTransaction(isolation);
            return new DbSession(conn,tran);
        }

    }
}


